/**
 * 项目名：	Rumba Plan
 * 
 * 版权所有(C)，上海海鼎信息工程股份有限公司，2006，所有权利保留。
 * 
 * 文件名：	BRolePermAgent.java
 * 模块说明：	
 * 修改历史：
 * 2006-9-30 - lxm - 创建。
 */
package com.hd123.rumba.user.biz;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.hibernate.Hibernate;
import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.type.Type;

import com.hd123.rumba.domain.IDomain;
import com.hd123.rumba.domain.IDomainMgr;
import com.hd123.rumba.exception.BusinessException;
import com.hd123.rumba.runtime.IBaseEntity;
import com.hd123.rumba.runtime.IManager;
import com.hd123.rumba.runtime.NamingMgr;
import com.hd123.rumba.runtime.OperateContext;
import com.hd123.rumba.user.CPermission;
import com.hd123.rumba.user.CRole;
import com.hd123.rumba.user.IPermission;
import com.hd123.rumba.user.IRole;
import com.hd123.rumba.user.IRoleMgr;
import com.hd123.rumba.user.IRolePermission;
import com.hd123.rumba.util.ClassifiedHashtable;

/**
 * 角色权限维护代理 | 业务层 | 实现类
 * 
 * @author lxm
 * 
 */
public class BRolePermAgent extends BPermAgent implements IBPermAgent {

  public void executeCommandsT(List<BPermissionCommand> cmds, OperateContext operate, long oca)
      throws BusinessException, HibernateException {
    checkIn();
    IRole prole = getRoleMgr().getRole(urUuid);
    ClassifiedHashtable h = checkOca(prole, oca, CRole.CAPTION_CLASS, prole.getNameCode());
    if (h != null)
      throw new BusinessException(h.getAllMessages());

    // root域的admin角色所拥有的权限被禁止修改。
    IDomain rootDomain = getDomainMgr().getRootDomain();
    if (prole.getDomain().getUuid().equals(rootDomain.getUuid())
        && CRole.VALUE_CODE_ROOT_ADMIN.equalsIgnoreCase(prole.getCode()))
      throw new BusinessException("禁止修改" + CRole.CAPTION_CLASS + "\"" + prole.getNameCode() + "@"
          + rootDomain.getNameCode() + "\"拥有的" + CPermission.CAPTION_CLASS + "。");

    // 构造内存权限表，并解释权限命令修改内存权限表。
    List havingPerms = fetchHavingPerms();
    Map<String, String> permMap = new HashMap();
    for (int i = 0; i < havingPerms.size(); i++) {
      String permCode = (String) havingPerms.get(i);
      permMap.put(permCode, permCode);
    }
    for (int i = 0; i < cmds.size(); i++) {
      BPermissionCommand cmd = cmds.get(i);
      List permList = fetchPermsByCmd(cmd);
      if (BPermissionCommand.VALUE_COMMAND_CHECKTOALL.equals(cmd.getCommand()))
        updateToCheckPerms(permList, permMap);
      else if (BPermissionCommand.VALUE_COMMAND_UNCHECKTOALL.equals(cmd.getCommand()))
        updateToUncheckPerms(permList, permMap);
      else if (BPermissionCommand.VALUE_COMMAND_READONLYTOALL.equals(cmd.getCommand()))
        updateToReadOnlyPerms(permList, permMap);
    }

    // 修改数据库
    Transaction tx = getSession().beginTransaction();
    try {
      // 比较并删除权限
      for (int i = 0; i < havingPerms.size(); i++) {
        String permCode = (String) havingPerms.get(i);
        if (permMap.get(permCode) == null) {
          IPermission pperm = getPermMgr().getPermissionByCode(permCode);
          getRoleMgr().removePermissionFromRole(pperm, prole, operate);
        }
      }
      // 比较并添加权限
      Object[] permArray = permMap.keySet().toArray();
      for (int i = 0; i < permArray.length; i++) {
        String permCode = (String) permArray[i];
        if (!havingPerms.contains(permCode)) {
          IPermission pperm = getPermMgr().getPermissionByCode(permCode);
          getRoleMgr().assignPermissionToRole(pperm, prole, operate);
        }
      }

      getRoleMgr().saveRole(prole, operate);
      tx.commit();
    } catch (Exception e) {
      tx.rollback();
      getSession().flush();
      throw new BusinessException(e);
    }
  }

  protected IBaseEntity getUserOrRole(String urUuid) throws BusinessException, HibernateException {
    return getRoleMgr().getRole(urUuid);
  }

  protected IManager getUserOrRoleMgr() throws BusinessException {
    return getRoleMgr();
  }

  protected Integer getHavingPermCount() throws BusinessException, HibernateException {
    List list = getSession().find(
        "select count(rp) from " + getRoleMgr().lookupClass(IRolePermission.class) + " rp"
            + " where rp.role.uuid = ?", urUuid, Hibernate.STRING);
    if (list.size() > 0)
      return (Integer) list.get(0);
    else
      return new Integer(0);
  }

  protected Integer getHavingPermCountInCFV(String cfvUuid) throws BusinessException,
      HibernateException {
    List list = getSession().find(
        "select count(distinct p) from " + getRoleMgr().lookupClass(IRolePermission.class) + " rp"
            + " inner join rp.permission p" + " where p.cartFuncViewUuid = ? and rp.role.uuid = ?",
        new Object[] {
            cfvUuid, urUuid }, new Type[] {
            Hibernate.STRING, Hibernate.STRING });
    if (list.size() > 0)
      return (Integer) list.get(0);
    else
      return new Integer(0);
  }

  protected Integer getHavingPermCountInProvider(String cfvUuid, BPermissionProvider provider)
      throws BusinessException, HibernateException {
    List list = getSession().find(
        "select count(p) from " + getRoleMgr().lookupClass(IRolePermission.class) + " rp"
            + " inner join rp.permission p"
            + " where rp.role.uuid = ? and p.cartFuncViewUuid = ? and p.provider.className = ?",
        new Object[] {
            urUuid, cfvUuid, provider.getClassName() }, new Type[] {
            Hibernate.STRING, Hibernate.STRING, Hibernate.STRING });
    if (list.size() > 0)
      return (Integer) list.get(0);
    else
      return new Integer(0);
  }

  protected Boolean hasPermission(IPermission pperm) throws BusinessException, HibernateException {
    List list = getSession().find(
        "from " + getRoleMgr().lookupClass(IRolePermission.class) + " rp"
            + " where rp.role.uuid = ? and rp.permission.uuid = ?", new Object[] {
            urUuid, pperm.getUuid() }, new Type[] {
            Hibernate.STRING, Hibernate.STRING });
    if (list.size() > 0)
      return Boolean.TRUE;
    else
      return Boolean.FALSE;
  }

  private IRoleMgr roleMgr = null;
  private IDomainMgr domainMgr = null;

  private IRoleMgr getRoleMgr() throws BusinessException {
    if (roleMgr == null)
      roleMgr = (IRoleMgr) NamingMgr.getInstance().lookupMgr(IRoleMgr.class);
    return roleMgr;
  }

  private IDomainMgr getDomainMgr() throws BusinessException {
    if (domainMgr == null)
      domainMgr = (IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class);
    return domainMgr;
  }

  /** 取得当前所拥有的权限集合。 */
  private List fetchHavingPerms() throws BusinessException, HibernateException {
    return getSession().find(
        "select rp.permission.code" + " from " + getRoleMgr().lookupClass(IRolePermission.class)
            + " rp" + " where rp.role.uuid = ?", urUuid, Hibernate.STRING);
  }

}
